package com.candy.reflectdemo;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * @author donglin
 * @Title: 反射工具类-Field类
 * @类名: Test01
 * @date 2020/6/4
 */
public class Test01 {
    public static void main(String[] args) {
        test03();
    }
    /*/**
     * 方法描述:通过反射机制获取一个类下的属性，并对属性进行操作
     *
     */
    public static void test03() {
        //实例化一个student对象
        Student stu=new Student();
        System.out.println("反射之前的stu对象"+stu);
        Student stu1=new Student();
        //第二种，通过实例对象.getClass（）方法获取
        Class type2=stu.getClass();
        try {
            //通过制定属性名，实例一个Field对象，注意带Declared的方法和不带Declared方法的区别
            Field stuName=type2.getDeclaredField("stuName");
            //由于私有属性不能随意操作，给他一个操作限权
            stuName.setAccessible(true);
            //使用set方法，对属性进行赋值操作
            stuName.set(stu,"张三");
            System.out.println("反射操作之后的stu对象"+stu);
            stuName.set(stu1,"李四");
            System.out.println("反射操作之后的stu1对象"+stu1);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
    /*/**
     * 方法描述:通过反射机制获取一个类下的属性
     *
     */
    public static void test02() {
        //通过类名.class获取Class对象
        Class type1=Student.class;
        //获取该类下的所有属性信息，不受访问控制修饰符限制
        Field[]  f= type1.getDeclaredFields();
        System.out.println(f.length);
        for (Field ff:f) {
        //遍历该类下所有属性信息，
        // getModifiers获取该属性的访问控制修饰符，返回值为int类型，需要使用Modifiers的toString方法进行转义；
        // getType()方法：获取该属性的数据类型，getSimpleName()：可去掉包名，得到简单的数据类型描述；
        // getName()方法：获取属性名；
            System.out.println(Modifier.toString(ff.getModifiers())+"\t"+ff.getType().getSimpleName()+"\t"+
                    ff.getName()+";");
        }
    }

    /*/**
     * 方法描述:获取Class对象
     *
    */
    public static void test01() {
        //获取Class对象的三种方式
        //第一种，通过类名.class获取
        Class type1=Student.class;
        Student stu=new Student();
        //第二种，通过实例对象.getClass（）方法获取
        Class type2=stu.getClass();
        try {
            //第三种，Class提供了一种静态方法，forName（包路径），获取
            Class type3=Class.forName("com.candy.reflectdemo.Student");
            //三种方式获取的用一个类的 类文件对象 是相同的
            System.out.println("type1==type2"+(type1==type2));
            System.out.println("type2==type3"+(type3==type2));
            System.out.println("type1==type3"+(type1==type3));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
